fix(apply-repo-settings): normalize bypass_actors order before diffing - #95
Merged
Conversation
jq -S only sorts object keys, not array element order. GitHub doesn't guarantee bypass_actors[] comes back in the same order settings.yml declares them, so the ruleset drift check flagged a permanent false "needs update" whenever the live and desired bypass_actors sets were identical but differently ordered — observed identically across require-pr, require-1-review, and require-codeowner-review on nsheaps/greasemonkey-scripts (workflow run 30285386587), traced back from nsheaps/.github#103/#45. Sort bypass_actors by (actor_type, actor_id) on both sides before the jq -S comparison so ordering differences no longer register as drift. Verified against the exact reported scenario (swapped actor_id order) and against a genuine-gap case (missing actor) to confirm real drift is still detected. Co-Authored-By: Claude Code (~/src/nsheaps/github-actions) <noreply@anthropic.com>
Triggered by: de8bdc4 Workflow run: https://github.com/nsheaps/github-actions/actions/runs/30288094498
nsheaps-oura
added a commit
that referenced
this pull request
Jul 27, 2026
…aults before diffing GitHub backfills two optional pull_request rule parameters that settings.yml often leaves unset: allowed_merge_methods (all three methods — merge, squash, rebase — regardless of what the repo itself allows) and required_reviewers (empty array). Neither default is declared in GitHub's OpenAPI schema or REST docs, so the ruleset diff treated their absence in settings.yml as a permanent mismatch against the live API response, even when nothing was actually misconfigured. Confirmed these defaults empirically rather than assuming them: read live rulesets on both nsheaps/greasemonkey-scripts and nsheaps/.github (which independently have allow_merge_commit:false at the repo level, yet both still return "merge" in allowed_merge_methods), and cross- checked GitHub's REST docs + OpenAPI schema, which state no default for either field. Backfill both fields on current vs. desired before the jq -S comparison (stacked on #95's ruleset-diff fix), only when actually absent so a genuine future restriction still registers as drift. Co-Authored-By: Claude Code (~/src/nsheaps/github-actions) <noreply@anthropic.com>
Merged
6 tasks
nsheaps-oura
added a commit
that referenced
this pull request
Jul 27, 2026
…aults before diffing (#96) GitHub backfills two optional pull_request rule parameters that settings.yml often leaves unset: allowed_merge_methods (all three methods — merge, squash, rebase — regardless of what the repo itself allows) and required_reviewers (empty array). Neither default is declared in GitHub's OpenAPI schema or REST docs, so the ruleset diff treated their absence in settings.yml as a permanent mismatch against the live API response, even when nothing was actually misconfigured. Confirmed these defaults empirically rather than assuming them: read live rulesets on both nsheaps/greasemonkey-scripts and nsheaps/.github (which independently have allow_merge_commit:false at the repo level, yet both still return "merge" in allowed_merge_methods), and cross- checked GitHub's REST docs + OpenAPI schema, which state no default for either field. Backfill both fields on current vs. desired before the jq -S comparison (stacked on #95's ruleset-diff fix), only when actually absent so a genuine future restriction still registers as drift. Co-authored-by: Claude Code (~/src/nsheaps/github-actions) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
apply-repo-settings's ruleset sync, traced fromnsheaps/.github#103/#45(an investigation into whether the automation app was actually configured as arequire-prbypass actor onnsheaps/greasemonkey-scripts).greasemonkey-scriptsmain under this exact ruleset. The apparent "still needs update" signal was a false positive in this action's drift-detection logic.Root cause
apply_rulesets()'s current-vs-desired comparison does:jq -Ssorts object keys, not array element order. GitHub doesn't guaranteebypass_actors[]comes back in the same ordersettings.ymldeclares them, so when the live and desired sets are identical but differently ordered, the plain string comparison reports drift forever.Confirmed via workflow run 30285386587 (dry-run dispatch of
apply-repo-settings.yamlonnsheaps/greasemonkey-scripts): the diff forrequire-pr(and identically forrequire-1-review,require-codeowner-review) showed the same two bypass actors present on both sides, just at swapped array positions — not a missing actor.Fix
Sort
bypass_actorsby a stable key (actor_type,actor_id) on bothcurrent_normanddesired_normbefore thejq -Scomparison, so ordering differences no longer register as drift.Test plan
bash -n— syntax check passes.shellcheck .github/actions/apply-repo-settings/action.sh— clean, no warnings.ruleset_filterjq expression and ran it standalone against synthetic JSON reproducing the reported scenario (two bypass actors present on both sides, swapped order) — confirmscurrent_norm == desired_normafter the fix (previously would differ).uses: nsheaps/github-actions/.../apply-repo-settings@mainby consumers, so a live check requires either this landing onmainor a consumer temporarily pointing at this branch — first live exercise will be the next realapply-repo-settingsdry-run/apply run once merged).Known separate issue (not fixed here)
The same dry-run log also showed
allowed_merge_methods/required_reviewers: []flip-flopping between current and desired — GitHub backfills some ruleparameterswith defaults thatsettings.ymlnever explicitly sets, causing a second, unrelated false-positive. Deliberately left out of this change to avoid guessing at GitHub's per-rule-type default-fill behavior without more research; flagged as a follow-up.🤖 Generated with Claude Code